#include "ScreenQuad.h"
#include "..\utils\Log.h"
#include "..\utils\Profiler.h"
#include "..\content\Material.h"
#include "..\content\Texture.h"

namespace ds {

ScreenQuad::~ScreenQuad(void) {
	//LOGC(logINFO,"ScreenQuad") << "destructing " << getName();
	delete m_Buffer;
}

void ScreenQuad::init() {	
	LOGC(logINFO,"ScreenQuad") << " " << getName() << "_ScreenQuad - init dynamic: " << m_Dynamic;
	m_Buffer = new TransformedTexturedBuffer(m_MaxVertices,m_MaxVertices*2,m_Dynamic);
	rebuild();
}

void ScreenQuad::add(float xp,float yp,float dimX,float dimY,const Rect& rect) {
	add(Vec3(xp,yp,1.0f),Vec3(dimX,dimY,0.0f),rect);
}

void ScreenQuad::add(const Vec3& pos,const Vec3& dimension,const Rect& textureRect) {
	Quad q;
	q.position = pos;
	Material* m = gEngine->getResourceManager().getMaterial(m_MaterialHandle);
	if ( m != 0 ) {
		Texture* tr = m->getTexture(0);
		if ( tr != 0 ) {
			q.tc.scale(textureRect,tr->getWidth());
			//q.uv[0] = (float)textureRect.left/(float)tr->getWidth();
			//q.uv[2] = (float)textureRect.right/(float)tr->getWidth();
			//q.uv[1] = (float)textureRect.top/(float)tr->getHeight();
			//q.uv[3] = (float)textureRect.bottom/(float)tr->getHeight();
		}
		else {
			//q.uv[0] = 0.0f;
			//q.uv[2] = 1.0f;
			//q.uv[1] = 0.0f;
			//q.uv[3] = 1.0f;
		}
	}
	q.dim[0] = dimension.x;
	q.dim[1] = dimension.y;
	q.dim[2] = dimension.z;
	m_Quads.append(q);
}

void ScreenQuad::rebuild() {		
	if ( m_Dynamic ) {
		PR_START(getName().c_str());
	}
	m_Buffer->clear();
	float u1,u2,v1,v2;
	int ar[6] = {0,1,2,1,3,2};
	u1 = v1 = 0.0f;
	u2 = v2 = 1.0f;
	float x, y , z;
	float dimX,dimY,dimZ;
	int idxOffset = 0;
	for ( size_t cnt = 0; cnt < m_Quads.num(); ++cnt ) {
		Quad* c = &m_Quads[cnt];
		x = c->position.x - 0.5f;
		y = c->position.y - 0.5f;
		z = c->position.z;

		//u1 = c->uv[0];
		//u2 = c->uv[2];
		//v1 = c->uv[1];
		//v2 = c->uv[3];

		dimX = c->dim[0] + 0.5f;
		dimY = c->dim[1] + 0.5f;
		dimZ = c->dim[2];

		// front 
		/*
		m_Buffer->add(TransformedTexturedVertex(x     ,y     , z, u1, v1));
		m_Buffer->add(TransformedTexturedVertex(x+dimX,y     , z, u2, v1));
		m_Buffer->add(TransformedTexturedVertex(x     ,y+dimY, z, u1, v2));
		m_Buffer->add(TransformedTexturedVertex(x+dimX,y+dimY, z, u2, v2));
		*/
		m_Buffer->add(TransformedTexturedVertex(x     ,y     , z, c->tc.u1, c->tc.v1));
		m_Buffer->add(TransformedTexturedVertex(x+dimX,y     , z, c->tc.u2, c->tc.v1));
		m_Buffer->add(TransformedTexturedVertex(x     ,y+dimY, z, c->tc.u1, c->tc.v2));
		m_Buffer->add(TransformedTexturedVertex(x+dimX,y+dimY, z, c->tc.u2, c->tc.v2));
		
		// create indices	
		for ( int i = 0; i < 6; ++i ) {
			m_Buffer->addIndex(ar[i]+idxOffset);
		}
		idxOffset += 4;
	}
	m_Buffer->update();
	if ( m_Dynamic ) {
		PR_END(getName().c_str());
	}
}

void ScreenQuad::prepareRendering() {
	PR_START(getName().c_str());
	m_Buffer->prepareData();
	PR_END(getName().c_str());
}

void ScreenQuad::draw() {
	PR_START(getName().c_str());
	m_Buffer->render(m_Quads.num()*2);	
	PR_END(getName().c_str());
}

void ScreenQuad::postRendering() {
	if ( m_Dynamic ) {
		m_Quads.clear();
	}
}



ColouredScreenQuad::~ColouredScreenQuad(void) {
	delete m_Buffer;
}

void ColouredScreenQuad::init() {	
	LOGC(logINFO,"ColouredScreenQuad") << getName() << "_ColouredScreenQuad - init dynamic: " << m_Dynamic;
	m_Buffer = new TransformedTextureColorBuffer(m_MaxVertices,m_MaxVertices*2,m_Dynamic);
	rebuild();
}

void ColouredScreenQuad::add(float xp,float yp,float dimX,float dimY,const Rect& rect,const Color& color,float angle) {
	add(Vec3(xp,yp,1.0f),Vec3(dimX,dimY,0.0f),rect,color,angle);
}

void ColouredScreenQuad::add(const Vec3& pos,const Vec3& dimension,const Rect& textureRect,const Color& color,float angle) {
	Quad q;
	q.position = pos;
	q.color = color;
	q.angle = angle;
	Material* m = gEngine->getResourceManager().getMaterial(m_MaterialHandle);
	if ( m != 0 ) {
		Texture* tr = m->getTexture(0);
		if ( tr != 0 ) {
			q.uv[0] = (float)textureRect.left/(float)tr->getWidth();
			q.uv[2] = (float)textureRect.right/(float)tr->getWidth();
			q.uv[1] = (float)textureRect.top/(float)tr->getHeight();
			q.uv[3] = (float)textureRect.bottom/(float)tr->getHeight();
		}
		else {
			q.uv[0] = 0.0f;
			q.uv[2] = 1.0f;
			q.uv[1] = 0.0f;
			q.uv[3] = 1.0f;
		}
	}
	q.dim[0] = dimension.x;
	q.dim[1] = dimension.y;
	q.dim[2] = dimension.z;
	m_Quads.append(q);
}

void ColouredScreenQuad::rebuild() {		
	if ( m_Dynamic ) {
		PR_START(getName().c_str());
	}
	m_Buffer->clear();
	float u1,u2,v1,v2;
	int ar[6] = {0,1,2,1,3,2};
	u1 = v1 = 0.0f;
	u2 = v2 = 1.0f;
	float x, y , z;
	float dimX,dimY,dimZ;
	int idxOffset = 0;
	for ( size_t cnt = 0; cnt < m_Quads.num(); ++cnt ) {
		Quad* c = &m_Quads[cnt];
		x = c->position.x - 0.5f;
		y = c->position.y - 0.5f;
		z = c->position.z;

		u1 = c->uv[0];
		u2 = c->uv[2];
		v1 = c->uv[1];
		v2 = c->uv[3];

		dimX = c->dim[0] + 0.5f;
		dimY = c->dim[1] + 0.5f;
		dimZ = c->dim[2];
		float angle = c->angle;
		if ( c->angle != 0.0f ) {			
			angle += DEGTORAD(225.0f);
			float centerX = x + dimX * 0.5f;
			float centerY = y + dimY * 0.5f;
			float rx = dimX * 0.5f;
			float ry = dimY * 0.5f;
			float r = sqrt(rx*rx + ry*ry);
			float xp = centerX + cos(angle) * r;
			float yp = centerY + sin(angle) * r;
			m_Buffer->add(TransformedTextureColorVertex(xp, yp, z, u1, v1,c->color));
			angle += DEGTORAD(90.0f);
			xp = centerX + cos(angle) * r;
			yp = centerY + sin(angle) * r;
			m_Buffer->add(TransformedTextureColorVertex(xp, yp, z, u2, v1,c->color));
			angle += DEGTORAD(180.0f);
			xp = centerX + cos(angle) * r;
			yp = centerY + sin(angle) * r;
			m_Buffer->add(TransformedTextureColorVertex(xp, yp, z, u1, v2,c->color));
			angle -= DEGTORAD(90.0f);
			xp = centerX + cos(angle) * r;
			yp = centerY + sin(angle) * r;
			m_Buffer->add(TransformedTextureColorVertex(xp, yp, z, u2, v2,c->color));

		}
		else {
			m_Buffer->add(TransformedTextureColorVertex(x, y, z, u1, v1,c->color));
			m_Buffer->add(TransformedTextureColorVertex(x+dimX, y, z, u2, v1,c->color));
			m_Buffer->add(TransformedTextureColorVertex(x, y+dimY, z, u1, v2,c->color));
			m_Buffer->add(TransformedTextureColorVertex(x+dimX, y+dimY, z, u2, v2,c->color));
		}
		// create indices	
		for ( int i = 0; i < 6; ++i ) {
			m_Buffer->addIndex(ar[i]+idxOffset);
		}
		idxOffset += 4;
	}
	m_Buffer->update();
	if ( m_Dynamic ) {
		PR_END(getName().c_str());
	}
}

void ColouredScreenQuad::prepareRendering() {
	PR_START(getName().c_str());
	m_Buffer->prepareData();
	PR_END(getName().c_str());
}

void ColouredScreenQuad::draw() {
	PR_START(getName().c_str());
	m_Buffer->render(m_Quads.num()*2);	
	PR_END(getName().c_str());
}

void ColouredScreenQuad::postRendering() {
	if ( m_Dynamic ) {
		m_Quads.clear();
	}
}
}